package com.ridanlabs.professorwebsite.models;

import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Id;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.NotSaved;
import com.ridanlabs.professorwebsite.general.Authority;

public class UserProfile {
	@Id private String id; //guaranteed to be unique/stable by google
	private String userEmail;
	private String firstName;
	private String lastName;
	private String schoolId;
	private int authorityBits;
	private HashSet<Key<Course>> courses;
	@NotSaved private Set<Authority> authorities;
	
	public UserProfile() {
		this.authorities = EnumSet.noneOf(Authority.class);
		courses = new HashSet<Key<Course>>();
	}
	
	public UserProfile(String id, String userEmail) {
		this.id = id;
		this.userEmail = userEmail;
		this.authorities = EnumSet.noneOf(Authority.class);
		this.authorities.add(Authority.NEW_USER);
		courses = new HashSet<Key<Course>>();
	}
	
	/*
	 * Getter/Setter functions.
	 */
	public String getId() { return this.id; }
	public void setId(String id) { this.id = id; }
	
	public String getUserEmail() { return this.userEmail; }
	public void setUserEmail(String userEmail) { this.userEmail = userEmail; }
	
	public String getFirstName() { return this.firstName; }
	public void setFirstName(String firstName) { this.firstName = firstName; }
	
	public String getLastName() { return this.lastName; }
	public void setLastName(String lastName) { this.lastName = lastName; }
	
	public String getSchoolId() { return this.schoolId; }
	public void setSchoolId(String schoolId) { this.schoolId = schoolId; }
	
	public Set<Authority> getAuthorities() { return this.authorities; }
	public void setAuthorities(Set<Authority> authorities) { this.authorities = authorities; }
	
	public HashSet<Key<Course>> getCourses() { return this.courses; }
	public void setCourses( HashSet<Key<Course>> courses ) { this.courses = courses; }
	
	public int getAuthorityBits() { return this.authorityBits; }
	public void setAuthorityBits(int authorityBits) { this.authorityBits = authorityBits; }
	
	/*
	 * Helper functions.
	 */
	public Key<UserProfile> getKey() {
		return new Key<UserProfile>(UserProfile.class, this.id);
	}
	
	public boolean addCourse( Key<Course> course ) {
		return this.courses.add(course);
	}
	
	/*
	 * Save/load processing.
	 */
	@SuppressWarnings("unused")
	@PostLoad //function called before loaded for consumption
	private void processOnLoad() {
		authorities = EnumSet.noneOf(Authority.class);
		for(Authority a : Authority.values()) {
			if ((authorityBits & (1 << a.getBit())) != 0) {
				authorities.add(a);
			}
		}
		
		if( courses == null )
			courses = new HashSet<Key<Course>>();
	}
	
	@SuppressWarnings("unused")
	@PrePersist //function called before save to datastore
	private void processOnSave() {
		authorityBits = 0; //set it to zero, in case authorities were deleted
		for(Authority a: authorities) {
			authorityBits |= 1 << a.getBit();
		}
	}
	
}
